﻿using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.Text;

namespace UtilsBase
{
    /// <summary>
    /// 在线生成密钥https://www.bchrt.com/tools/rsa/， 可以与java 互通
    /// </summary>
    public class UtilsRsaHelper
    {
        private static Encoding Encoding_UTF8 = Encoding.UTF8;

        public void test()
        {
            UtilsRsaHelper rSAHelper = new UtilsRsaHelper();
            var rsaKey = rSAHelper.GetKey();
            var privateKey = rsaKey.PrivateKey;
            var publicKey = rsaKey.PublicKey;
            Console.WriteLine($"公钥:{privateKey}");
            Console.WriteLine($"私钥:{publicKey}");
            privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDT1xYa6f1v/HJy6Yw5jnYG40NByV0BPFhLL/PAf8CzCCNHhBfJ8PXdXFdwki8jf/hjodfJTYdaKc8HEkM9hMGOR2CQpzaPBwCRwEtaS4d3HI2DBouET9GsbYbxS0pE1Jed7/ga2BZTg3G49NNDBnQ31cvJ8muslSqqFQdAnKonvK8swQraZ/76fNAaeyzTG5/n7Y4SWe/nCGUR0xDi3h1Ye84M99t3+CFu9J1AqBLQwsCHY+5Toe41jfpIGpFlggPv8lxGlSXHnC8QoEF0utWB+syzg/VSQ000AFCxG6Pk7tNb7ObR5dXgBwLajmWbxng0aJJ0sUQfqQBMzw8rgbLFAgMBAAECggEAPKExpXBU5elFxFfNl2eLpjsDM9/y63ie+J330J9/wn3QwxYuTNDXPYzBRenA7hMhPzrB7M5wr8CJjUeP0Rqe3x7Up3IELnldk1mK94PoeJHGerqz0aGarBQI7CSVVA/YeQ6GXwB7m1liggIoOOWu+5AILHtij9l9hYJROg/cr1RPJB4UHyW7J/6RUa1YbFD2NVUnye5qx0okmIqWpA7v3jjPDNdSNpEGI5u/2MlFUZH+6db7ThbaowMq+7vMgI09wixd1Fcqw2u/gECmi2x4NpFJjmhFgS0q26/ZXh/t1I7IrnpnQhgbEG1fAXpbL9LxNyftn4cXtLAA6vpxTtTF/QKBgQDuVfo/a784FmrLYtpaDvmp47pF/UDgK9VemDn5Q0Mw3H5QkujW/8HI/IpnIRviSWGH4fMYtUzYU5zCplK7QyelWWfRt7iKDK1SrmQybdlKz/aZiOuX9a+kKBSq7TWZSGcROp9pJ0Wu38tPOVaGGe6PYreuy6qeJpK3vfVdoU/uTwKBgQDjimXjjyvgtBZCPX6lkVsgVehIaKZMIPKwZl15avu7UjsisYifXW5joT5W+xrvX9KoqNqwLi7AVlZL1StQtEiRZRCKI5KwI9OQwkL0LgYjPcD+h4BG2X1tSG1YkjcH3Iu6CHmzfQWY+Fatp2VeAqBcTyTEDvD1RbLVh+mCBs08qwKBgD4G4jnfMMTIEMMd1vXZL+CnA7NzVY8B2WXk+DGG79WnjLgrg61wol5MWzi7xSX/MwLKKxojFPy3xfRilOVndMnzmrFZvw0uf20lNa5qKELwHJ2YpLfHmQ5/3+EcGvbpgOla+GHFdr0sQR09Lud3mD540pULLDw8jbKEHXdgpAzBAoGAaKecK2kLdmN+JWNhX8eWUS4SE1PGwRcaaJX8gj75n3O37UIYo6v2fO6J3LnL7rN1EcvwIb5sFFzhfimCrbDt+6mvTMoFyuv/gAJJh0Ov4P+jR66NCok4Dk6UtHszwnLm9V62kx56t5vpSh/HGNE+bpacQ2zX2QgAtAO6G+sC9NcCgYBwoi05BnOcUrtXt+XVT11kYN2OlJt3WdWvtj5vaFADM+oTSZOS/l/7GlJM7xZWv6b12NNZJ4+hk0xUqsq0ZBzPugPGmg+/ISPLTT4RmgIAbQZn2hzt1+SQRIkr5iqg/x1BI4dvF8y0xmPoUSEvSEgbF59rafjUHKYGMgZtSOiasA==";
            publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA09cWGun9b/xycumMOY52BuNDQcldATxYSy/zwH/AswgjR4QXyfD13VxXcJIvI3/4Y6HXyU2HWinPBxJDPYTBjkdgkKc2jwcAkcBLWkuHdxyNgwaLhE/RrG2G8UtKRNSXne/4GtgWU4NxuPTTQwZ0N9XLyfJrrJUqqhUHQJyqJ7yvLMEK2mf++nzQGnss0xuf5+2OElnv5whlEdMQ4t4dWHvODPfbd/ghbvSdQKgS0MLAh2PuU6HuNY36SBqRZYID7/JcRpUlx5wvEKBBdLrVgfrMs4P1UkNNNABQsRuj5O7TW+zm0eXV4AcC2o5lm8Z4NGiSdLFEH6kATM8PK4GyxQIDAQAB";

            var data = "待加密的文字内容";
            var jiami = rSAHelper.EncryptByPrivateKey(data, privateKey);
            Console.WriteLine(jiami);

            string sijiamicontent = "y5+25O4jCNhQfDdQaGGocyuZa4LO+ZZH4Lr9yJ+hahmMxAQh4tVpAoUbFlGCF2dQKObk1UadYtqZDG4zjlt/venbeay861L9LAPPZ7rvf0rQ3QL2Gagy9IYstgru3+Oc+J1YCCJ00eHYRRoFSfMZUyd4TIeIY9+NWP4fWipLQZIklfvryLXRQ2oiQk3U9go4VJB2W9udRtu4NjJ60T2+0dtzvw7Ml6JvugHXULm4T0IwJoMx/yGrzR4tO7Mkf5XB58iltv/N3vHhsanguz9PqchKRBmxFnFV8OAZEK23iuJg87El2sTc7jFBTjDSQAVpKT0HaBhfz+hHAQBX/0rveg==";

            var jiemi = rSAHelper.DecryptByPublicKey(sijiamicontent, publicKey);
            Console.WriteLine("解密结果:" + jiemi);
        }

        /// <summary>
        /// KEY 结构体
        /// </summary>
        public struct RSAKEY
        {
            /// <summary>
            /// 公钥
            /// </summary>
            public string PublicKey { get; set; }
            /// <summary>
            /// 私钥
            /// </summary>
            public string PrivateKey { get; set; }
        }
        public RSAKEY GetKey()
        {
            //RSA密钥对的构造器
            RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();

            //RSA密钥构造器的参数
            RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
                Org.BouncyCastle.Math.BigInteger.ValueOf(3),
                new SecureRandom(),
                1024,   //密钥长度
                25);
            //用参数初始化密钥构造器
            keyGenerator.Init(param);
            //产生密钥对
            AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
            //获取公钥和密钥
            AsymmetricKeyParameter publicKey = keyPair.Public;
            AsymmetricKeyParameter privateKey = keyPair.Private;

            SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);

            Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();

            byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
            Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
            byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8");

            RSAKEY item = new RSAKEY()
            {
                PublicKey = Convert.ToBase64String(publicInfoByte),
                PrivateKey = Convert.ToBase64String(privateInfoByte)
            };
            return item;
        }
        private AsymmetricKeyParameter GetPublicKeyParameter(string keyBase64)
        {
            keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            byte[] publicInfoByte = Convert.FromBase64String(keyBase64);
            Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取，从本地导入
            AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
            return pubKey;
        }

        private AsymmetricKeyParameter GetPrivateKeyParameter(string keyBase64)
        {
            keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            byte[] privateInfoByte = Convert.FromBase64String(keyBase64);
            // Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取，从本地导入
            // PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
            return priKey;
        }

        /// <summary>
        /// 私钥加密
        /// </summary>
        /// <param name="data">加密内容</param>
        /// <param name="privateKey">私钥（Base64后的）</param>
        /// <returns>返回Base64内容</returns>
        public string EncryptByPrivateKey(string data, string privateKey)
        {
            //非对称加密算法，加解密用
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());

            //加密
            try
            {
                engine.Init(true, GetPrivateKeyParameter(privateKey));
                byte[] byteData = Encoding_UTF8.GetBytes(data);
                var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
                return Convert.ToBase64String(ResultData);
                //Console.WriteLine("密文（base64编码）:" + Convert.ToBase64String(testData) + Environment.NewLine);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 私钥解密
        /// </summary>
        /// <param name="data">待解密的内容</param>
        /// <param name="privateKey">私钥（Base64编码后的）</param>
        /// <returns>返回明文</returns>
        public string DecryptByPrivateKey(string data, string privateKey)
        {
            data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            //非对称加密算法，加解密用
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());

            //解密
            try
            {
                engine.Init(false, GetPrivateKeyParameter(privateKey));
                byte[] byteData = Convert.FromBase64String(data);
                var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
                return Encoding_UTF8.GetString(ResultData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 公钥加密
        /// </summary>
        /// <param name="data">加密内容</param>
        /// <param name="publicKey">公钥（Base64编码后的）</param>
        /// <returns>返回Base64内容</returns>
        public string EncryptByPublicKey(string data, string publicKey)
        {
            //非对称加密算法，加解密用
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());

            //加密
            try
            {
                engine.Init(true, GetPublicKeyParameter(publicKey));
                byte[] byteData = Encoding_UTF8.GetBytes(data);
                var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
                return Convert.ToBase64String(ResultData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 公钥解密
        /// </summary>
        /// <param name="data">待解密的内容</param>
        /// <param name="publicKey">公钥（Base64编码后的）</param>
        /// <returns>返回明文</returns>
        public string DecryptByPublicKey(string data, string publicKey)
        {
            data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            //非对称加密算法，加解密用
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());

            //解密
            try
            {
                engine.Init(false, GetPublicKeyParameter(publicKey));
                byte[] byteData = Convert.FromBase64String(data);
                var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
                return Encoding_UTF8.GetString(ResultData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
